package com.zero.jewelry.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zero.common.core.domain.page.PageDomain;
import com.zero.common.core.utils.DateUtils;
import com.zero.common.core.utils.bean.BeanUtils;
import com.zero.jewelry.custom.annotaion.ReMoveRedisCacheAtLast;
import com.zero.jewelry.custom.constant.MyJewelryConstant;
import com.zero.jewelry.domain.*;
import com.zero.jewelry.service.*;
import com.zero.jewelry.vo.ProductRelsVo;
import com.zero.jewelry.vo.ProductVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zero.common.annotation.log.Log;
import com.zero.common.core.basecontroller.BaseController;
import com.zero.common.core.domain.result.AjaxResult;
import com.zero.common.core.enums.BusinessType;
import com.zero.common.core.utils.poi.ExcelUtil;
import com.zero.common.core.domain.page.TableDataInfo;

/**
 * 产品管理Controller
 *
 * @author cai-xu-kun
 * @date 2025-07-29
 */
@RestController
@RequiredArgsConstructor
@Api(tags = "产品管理")
@RequestMapping("/jewelry/product")
public class ProductController extends BaseController {

    private final IProductService productService;
    private final IProductCategoryRelService productCategoryRelService;
    private final IProductTagRelService productTagRelService;
    private final IProductPartitionRelService productPartitionRelService;
    private final IBraceletService braceletService;


    /**
     * 新增产品管理
     */
    @ApiOperation("新增产品管理")
    @PreAuthorize("@ss.hasPermi('jewelry:product:add')")
    @Log(title = "产品管理", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional(rollbackFor = Exception.class)
    @ReMoveRedisCacheAtLast(MyJewelryConstant.ALL_PRODUCT)
    public AjaxResult add(@RequestBody ProductVo vo) {
        Product product = vo.getProduct();
        productService.save(product);
        Long productId = product.getId();//  1.....2.....3......
        List<ProductCategoryRel> relsC = new ArrayList<>();
        for (Long categoryId : vo.getCategoryIds()) {
            ProductCategoryRel rel = new ProductCategoryRel(productId, categoryId);
            relsC.add(rel);
        }
        List<ProductTagRel> relsT = new ArrayList<>();
        for (Long tagId : vo.getTagIds()) {
            ProductTagRel rel = new ProductTagRel(productId, tagId);
            relsT.add(rel);
        }
        List<ProductPartitionRel> relsP = new ArrayList<>();
        for (Long prodPartitionId : vo.getProdPartitionIds()) {
            ProductPartitionRel rel = new ProductPartitionRel(productId, prodPartitionId);
            relsP.add(rel);
        }
        productCategoryRelService.saveBatch(relsC);
        productTagRelService.saveBatch(relsT);
        productPartitionRelService.saveBatch(relsP);

        //尺码数据,如果为空不保存
        List<Bracelet> bracelets = vo.getBraceletSizes();
        if (bracelets != null && !bracelets.isEmpty()){
            bracelets.forEach(bracelet -> {
                bracelet.setProductId(productId);
                bracelet.setCreateTime(DateUtils.getNowDate());
            });
            braceletService.saveBatch(bracelets);
        }

        return toAjax(1);
    }

    /**
     * 修改产品分类
     */
    @ApiOperation("修改产品")
    @PreAuthorize("@ss.hasPermi('jewelry:product:edit')")
    @Log(title = "产品管理", businessType = BusinessType.UPDATE)
    @PutMapping
    @Transactional(rollbackFor = Exception.class)
    @ReMoveRedisCacheAtLast(MyJewelryConstant.ALL_PRODUCT)
    public AjaxResult edit(@RequestBody ProductVo vo){
        //1.更新产品信息（名称，价格）
        Product product = vo.getProduct();
        productService.updateProduct(product);
        Long productId = product.getId();
        //2. 删除该产品原有的关联的关系（必须先删除旧的，再插新的）
        productCategoryRelService.remove(new LambdaQueryWrapper<ProductCategoryRel>()
                .eq(ProductCategoryRel::getProductId,productId));
        //3. 根据前端传的新分类ID，插入新的关联关系
        List<ProductCategoryRel> relsC = new ArrayList<>();
        for (Long categoryId : vo.getCategoryIds()) {
            ProductCategoryRel rel = new ProductCategoryRel(productId, categoryId);
            relsC.add(rel);
        }
        productTagRelService.remove(new LambdaQueryWrapper<ProductTagRel>()
                .eq(ProductTagRel::getProductId,productId));
        //3. 根据前端传的新分类ID，插入新的关联关系
        List<ProductTagRel> relsT = new ArrayList<>();
        for (Long tagId : vo.getTagIds()) {
            ProductTagRel rel = new ProductTagRel(productId, tagId);
            relsT.add(rel);
        }
        productPartitionRelService.remove(new LambdaQueryWrapper<ProductPartitionRel>()
                .eq(ProductPartitionRel::getProductId,productId));
        List<ProductPartitionRel> relsP = new ArrayList<>();
        for (Long prodPartitionId : vo.getProdPartitionIds()) {
            ProductPartitionRel rel = new ProductPartitionRel(productId, prodPartitionId);
            relsP.add(rel);
        }

        //尺码数据，先删除再保存
        braceletService.remove(new LambdaQueryWrapper<Bracelet>()
                .eq(Bracelet::getProductId,productId));
        List<Bracelet> bracelets = vo.getBraceletSizes();
        if (bracelets != null && !bracelets.isEmpty()){
            bracelets.forEach(bracelet -> {
                bracelet.setProductId(productId);
                bracelet.setCreateTime(DateUtils.getNowDate());
            });
            braceletService.saveBatch(bracelets);
        }

        productCategoryRelService.saveBatch(relsC);
        productTagRelService.saveBatch(relsT);
        productPartitionRelService.saveBatch(relsP);
        return toAjax(1);
    }

    /**
     * 查询已选分类，分区，标签，品牌
     */
    @ApiOperation("获取已选分类，分区，标签，品牌")
    @PreAuthorize("@ss.hasPermi('jewelry:product:query')")
    @GetMapping(value = "/getAllRels/{id}")
    public AjaxResult get(@PathVariable("id") Long id) {
//        List<ProductCategoryRel> productCategoryRels = productCategoryRelService.list(new LambdaQueryWrapper<ProductCategoryRel>()
//                .eq(ProductCategoryRel::getCategoryId, id));
//        List<Long> cIds = productCategoryRels.stream().map(ProductCategoryRel::getCategoryId).collect(Collectors.toList());
//
//        List<ProductTagRel> productTagRels = productTagRelService.list(new LambdaQueryWrapper<ProductTagRel>()
//                .eq(ProductTagRel::getTagId,id));
//        List<Long> tIds = productTagRels.stream().map(ProductTagRel::getTagId).collect(Collectors.toList());
//
//        List<ProductPartitionRel> productPartitionRels = productPartitionRelService.list(new LambdaQueryWrapper<ProductPartitionRel>()
//                .eq(ProductPartitionRel::getPartitionId,id));
//        List<Long> pIds = productPartitionRels.stream().map(ProductPartitionRel::getPartitionId).collect(Collectors.toList());
//        return success(new ProductRelsVo(cIds,tIds,pIds));
        List<ProductCategoryRel> productCategoryRels = productCategoryRelService.list(new LambdaQueryWrapper<ProductCategoryRel>()
                .eq(ProductCategoryRel::getProductId, id));
        List<ProductTagRel> productTagRels = productTagRelService.list(new LambdaQueryWrapper<ProductTagRel>()
                .eq(ProductTagRel::getProductId, id));
        List<ProductPartitionRel> productPartitionRels = productPartitionRelService.list(new LambdaQueryWrapper<ProductPartitionRel>()
                .eq(ProductPartitionRel::getProductId, id));

        List<Long> cIds = productCategoryRels.stream().map(ProductCategoryRel::getCategoryId).collect(Collectors.toList());
        List<Long> tIds = productTagRels.stream().map(ProductTagRel::getTagId).collect(Collectors.toList());
        List<Long> pIds = productPartitionRels.stream().map(ProductPartitionRel::getPartitionId).collect(Collectors.toList());

        cIds = cIds == null ? new ArrayList<>() : cIds;
        tIds = tIds == null ? new ArrayList<>() : tIds;
        pIds = pIds == null ? new ArrayList<>() : pIds;

        return success(new ProductRelsVo(cIds, tIds, pIds));
    }

    /**
     * 复制商品
     */
    @ApiOperation("复制商品")
    @PreAuthorize("@ss.hasPermi('jewelry:product:add')")
    @Log(title = "产品管理", businessType = BusinessType.INSERT)
    @PostMapping("/copy/{id}")
    @Transactional(rollbackFor = Exception.class)
    @ReMoveRedisCacheAtLast(MyJewelryConstant.ALL_PRODUCT)
    public AjaxResult copyProduct(@PathVariable("id") Long id){
        Product originalProduct = productService.selectProductById(id);

        Product product = new Product();
        //除了"id", "pid", "createTime", "updateTime"不复制； 将父id给pid
        BeanUtils.copyProperties(originalProduct, product, "id", "pid", "createTime", "updateTime");
        product.setPid(id);
        // 自动添加“（某某某的复制）”后缀
        product.setName(  originalProduct.getName() + "（复制）");
        System.out.println("新名称：" + product.getName());
        //将复制的存进数据库
        boolean saveSuccess = productService.save(product);
        return AjaxResult.success(saveSuccess);
    }

/** ========================================================================= */

    /**
     * 查询产品管理分页
     */
    @ApiOperation("查询产品管理分页")
    @PreAuthorize("@ss.hasPermi('jewelry:product:list')")
    @GetMapping("/list")
    public TableDataInfo list(Product product) {
        PageDomain pageDomain = this.startPage();
        Page<Product> p = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        
        Page<Product> page = null;
        if (product.getPid() == null) {
            page = productService.selectProductListPage(product, p);
        } else {
            //创建逆序查询条件构件器,按ID倒序排序
            LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();

            queryWrapper.orderByDesc(Product::getId);
            queryWrapper.and(q -> {
                q.eq(Product::getPid, product.getPid())
                        .or()
                        .eq(Product::getId, product.getPid());
            });
            page = productService.listParentAndSons(p, queryWrapper);
        }


        return this.getDataTable(page);
    }

    /**
     * 导出产品管理列表
     */
    @ApiOperation("导出产品管理列表")
    @PreAuthorize("@ss.hasPermi('jewelry:product:export')")
    @Log(title = "产品管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Product product) {
        List<Product> list = productService.selectProductList(product);
        ExcelUtil<Product> util = new ExcelUtil<Product>(Product.class);
        util.exportExcel(response, list, "产品管理数据");
    }

    /**
     * 获取产品管理详细信息
     */
    @ApiOperation("获取产品管理详细信息")
    @PreAuthorize("@ss.hasPermi('jewelry:product:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(productService.selectProductById(id));
    }

    /**
     * 删除产品管理
     */
    @ApiOperation("删除产品管理")
    @PreAuthorize("@ss.hasPermi('jewelry:product:remove')")
    @Log(title = "产品管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    @ReMoveRedisCacheAtLast(MyJewelryConstant.ALL_PRODUCT)
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(productService.deleteProductByIds(ids));
    }
}
